import { EBundleType, EResType } from "../Common/Enum";
import AudioManager from "./AudioManager";
import GameUtil from "./GameUtil";
import ResManager from "./ResManager";

export class LoadUtil {
	private static _instance: LoadUtil;
	public static get instance(): LoadUtil {
		if (!this._instance) {
			this._instance = new LoadUtil();
		}
		return this._instance;
	}

	public loadResAny(url: string, resType: any, callBack?: Function) {
		cc.resources.load(url, resType, (error: any, res: any) => {
			if (error) {
				console.error(error);
				return;
			}
			callBack && callBack(res);
			callBack = null;
		});
	};

	public loadScene(sceneName: string, callFunc: any, isClear = true) {
		if (isClear) {
			ResManager.instance.clear();
		}
		cc.director.preloadScene(sceneName, () => {
			cc.director.loadScene(sceneName, callFunc);
		});
	};

	public setSpriteFrame(sprite: cc.Sprite, resType: EResType, id?: number | string, maxWidth?: number, maxHeight?: number) {
		const data = GameUtil.instance.getResUrlByType(resType, id);
		this.loadRes(data.bundle, data.url, cc.SpriteFrame, async (err, res) => {
			if (res instanceof cc.Texture2D) {
				sprite.spriteFrame = new cc.SpriteFrame(res);
				sprite.node.width = res.width;
				sprite.node.height = res.height;
			} else {
				sprite.spriteFrame = res;
			}
			
			// 设置缩放
			if (maxWidth && maxWidth > 0 && maxHeight && maxHeight > 0) {
				const sx = maxWidth / sprite.node.width;
				const sy = maxHeight / sprite.node.height;
				sprite.node.scale = Math.min(sx, sy);
			}
		});
	}

	public loadSpineAsset(bundleType: EBundleType, url: string, complete: Function) {
		this.loadRes(bundleType, url, sp.SkeletonData, (err, res) => {
			if (res instanceof sp.SkeletonData) {
				complete && complete();
				complete = null;
			}
		});
	}

	public loadDragonAsset(ske, bundleType: EBundleType, url: string, complete: Function) {
		this.loadRes(bundleType, url + '_tex', dragonBones.DragonBonesAtlasAsset, (err, atlasasset) => {
			if (!err) {
				ske.dragonAtlasAsset = atlasasset;
				this.loadRes(bundleType, url + '_ske', dragonBones.DragonBonesAsset, (err, asset) => {
					if (!err) {
						ske.dragonAsset = asset;
						ske.armatureName = "Armature";
						complete && complete(ske);
					} else {
						err && console.log('url1', url, bundleType);
					}
				});
			}
		});
	}

	public loadRes(bundleType: EBundleType, url: string, type: any, complete: Function) {
		this.loadBundle(bundleType, (bundle/*: cc.AssetManager.Bundle*/) => {
			const res = bundle.get(url);
			if (res) {
				complete(null, res);
			} else if (type) {
				bundle.load(url, type, complete);
			} else {
				bundle.load(url, complete);
			}
		});
	}

	public loadBundle(bundleType: EBundleType | string, complete: Function) {
		const bundle = cc.assetManager.getBundle(bundleType);
		if (!bundle) {
			cc.assetManager.loadBundle(bundleType, (err, res) => {
				if (err) {
					console.log(`LoadUtil.loadBundle()===>${bundleType}:${err}`);
					return;
				}
				this.loadDir(bundleType, null);
				complete && complete(res);
			})
		} else {
			complete && complete(bundle);
		}
	}

	public loadDir(type: EBundleType | string, complete: Function) {
		this.loadBundle(type, (bundle: cc.AssetManager.Bundle) => {
			bundle.loadDir("", (error, assets) => {
				if (error) {
					return;
				}
				for (let i = 0; i < assets.length; i++) {
					if (assets[i].name != '') {
						if (assets[i] instanceof cc.AudioClip) {
							AudioManager.instance.audioDatas.set(assets[i].name, assets[i]);
							ResManager.instance.set(assets[i], cc.AudioClip);
						} else if (assets[i] instanceof cc.Prefab) {
							// ResModel._ins.PrefabDic.set(assets[i].name, assets[i]);
						} else if (assets[i] instanceof cc.SpriteFrame) {
							// ResModel._ins.SpriteFrameDic.set(assets[i].name, assets[i]);
						} else if (assets[i] instanceof sp.SkeletonData) {
							ResManager.instance.set(assets[i], sp.SkeletonData);
						} else {
							// console.log("其他:", typeof assets[i]);
						}
					}
				}
				// console.log('loadBundle:', type, AudioManager.instance.audioDatas);
				// console.log('loadBundle:', type, ResManager.instance.cacheRes);
				complete && complete();
			});
		});
	}

	/**
	 * 清理资源缓存
	 * @param {Function} callback 清理完成后的回调函数
	 */
	public clearCache(callback) {
		// // 使用cc.assetManager.cacheManager来获取缓存信息
		// const cacheManager = cc.assetManager.cacheManager;

		// // 获取所有缓存资源的引用计数
		// const refCountMap = cacheManager.getRefCountMap();

		// // 创建一个临时的数组来存储需要释放的资源
		// const assetsToRelease = [];

		// // 遍历引用计数映射，将计数为1的资源（即不被任何其他对象引用的资源）添加到释放数组中
		// for (const [uuid, refCount] of refCountMap) {
		// 	if (refCount === 1) {
		// 		assetsToRelease.push(uuid);
		// 	}
		// }

		// // 使用cacheManager的release方法来释放这些资源
		// cacheManager.release(assetsToRelease, function () {
		// 	// 回调函数，在资源释放完成后执行
		// 	callback && callback();
		// });
	}

	public removeBundle(type: EBundleType) {
		const bundle = cc.assetManager.getBundle(type);
		if (bundle) {
			bundle.releaseAll();
			cc.assetManager.removeBundle(bundle);
		} else {
			console.log(`LoadUtil.removeBundle()===>bundle:${type}不存在~`);
		}
	}

	/** 根据配置 返回正确的url */
	private getBundleUrl(config: any, bundleName: string) {
		if (config["bundles"] && config["bundles"].indexOf(bundleName) >= 0) {
			return config.oldUrl + bundleName;
		}
		return bundleName;
	};
}


// let bundle = assetManager.getBundle(BUNDLE_NAME);
// if (!bundle) {
//   this.tipLabel.string = "操作失败,请先点击加载Bundle";
//   return;
// }

// // 加载预制体页面
// bundle.load("testLayer", Prefab, (err, prefab) => {
//   if (err) {
//     return console.error(err.message);
//   }

//   let layerNode = instantiate(prefab);
//   layerNode.parent = this.node;
// });

// // 加载纹理
// bundle.load("icon/texture", Texture2D, (err, texture) => {
//   if (err) {
//     return console.error(err.message);
//   }

//   let node = new Node("sprite");
//   node.layer = Layers.Enum.UI_2D;
//   node.setPosition(0, 0, 0);
//   node.scale = v3(0.5, 0.5, 0.5);
//   let sprite = node.addComponent(Sprite);
//   const spriteFrame = new SpriteFrame();
//   spriteFrame.texture = texture;
//   sprite.spriteFrame = spriteFrame;
//   node.parent = this.tipLabel.node.parent;
// });

// // 加载场景
// bundle.loadScene("subScene", (err, scene) => {
//   if (err) {
//     return console.error(err.message);
//   }
//   director.runScene(scene);
// });